package com.shr25.robot.qq.plugin;

import cn.hutool.core.img.gif.AnimatedGifEncoder;
import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.shr25.robot.common.RobotMsgPermission;
import com.shr25.robot.common.RobotMsgType;
import com.shr25.robot.qq.conf.QqConfig;
import com.shr25.robot.qq.model.QqMessage;
import com.shr25.robot.qq.plugins.RobotPlugin;
import com.shr25.robot.qq.util.MessageUtil;
import kotlin.io.FilesKt;
import net.mamoe.mirai.contact.User;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.utils.BotConfiguration;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @description: 摸头插件
 * @author:: huobing
 * @date: 2022-7-9  20:08
 **/
@Component
public class PatHeadPlugin extends RobotPlugin {
    private Map<String, net.mamoe.mirai.message.data.Image> images = new HashMap<>();

    public PatHeadPlugin() {
        super("摸头插件");
        addDesc("摸头插件");
        addCommand("摸头",  "生成摸自己头像的动图", RobotMsgPermission.MEMBER, new RobotMsgType[]{RobotMsgType.Group}, (qqMessage) -> {
            User user = qqMessage.getSender();
            if (user != null) {
                try {
                    net.mamoe.mirai.message.data.Image image = getPat(user, 80);
                    qqMessage.putReplyMessage(image);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return true;
        }, true);
        addCommand("摸",  "摸 @{群员}生成摸群员头像的动图", new RobotMsgType[]{RobotMsgType.Group}, (qqMessage) -> {
            User user = null;
            if(qqMessage.getContent().trim().startsWith("@")){
                String nick = qqMessage.getContent().trim().replace("@", "");
                user = MessageUtil.getGroupMember(qqMessage.getGroup(), nick);
            }else{
                AtomicReference<Long> qq = new AtomicReference<>();
                qqMessage.getMessageEvent().getMessage().forEach(singleMessage -> {
                    // 过滤艾特消息
                    if (singleMessage instanceof At) {
                        qq.set(((At) singleMessage).getTarget());

                    }
                });
                if(qq.get() != null){
                    user = MessageUtil.getGroupMember(qqMessage.getGroup(), qq.get());
                }
            }
            if (user != null) {
                try {
                    net.mamoe.mirai.message.data.Image image = getPat(user, 80);
                    qqMessage.putReplyMessage(image);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
            return true;
        }, true);
        setSort(10001);
    }

    public net.mamoe.mirai.message.data.Image getPat(User user, Integer delay) throws Exception {
        if(images.containsKey(user.getAvatarUrl())){
            return images.get(user.getAvatarUrl());
        }else{
            // 媒体文件夹
            File tempPath = FilesKt.resolve(BotConfiguration.getDefault().getWorkingDir(), SpringUtil.getBean(QqConfig.class).getWorkspace() + File.separator + "temp" + File.separator);
            FileUtil.mkdir(tempPath);
            String imgPath = tempPath.getAbsolutePath()+File.separator+UUID.randomUUID().toString()+".gif";
            File tmp = mkImg(user.getAvatarUrl(), imgPath,delay);
            net.mamoe.mirai.message.data.Image image = MessageUtil.buildImageMessage(user, tmp);
            images.put(user.getAvatarUrl(), image);
            tmp.delete();
            return image;
        }
    }
    private File mkImg(String avatarUrl, String imgPath, Integer delay) throws Exception {
        BufferedImage avatarImage = ImageIO.read(new URL(avatarUrl));
        Integer targetSize = avatarImage.getWidth();
        BufferedImage roundImage = new BufferedImage(targetSize, targetSize, 2);
        Graphics2D roundImageGraphics2D = roundImage.createGraphics();
        roundImageGraphics2D.setComposite(AlphaComposite.Src);
        roundImageGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        roundImageGraphics2D.setColor(Color.WHITE);
        roundImageGraphics2D.fill((new RoundRectangle2D.Float(0.0F, 0.0F, (float)targetSize, (float)targetSize, (float)targetSize, (float)targetSize)));
        roundImageGraphics2D.setComposite(AlphaComposite.SrcAtop);
        roundImageGraphics2D.drawImage(avatarImage, 0, 0, targetSize, targetSize, (ImageObserver)null);
        roundImageGraphics2D.dispose();
        Image avatar = roundImage.getScaledInstance(112, 112, 4);
        BufferedImage p1 = processImage(avatar, 0, 100, 100, 12, 16, 0);
        BufferedImage p2 = processImage(avatar, 1, 105, 88, 12, 28, 0);
        BufferedImage p3 = processImage(avatar, 2, 110, 76, 12, 40, 6);
        BufferedImage p4 = processImage(avatar, 3, 107, 84, 12, 32, 0);
        BufferedImage p5 = processImage(avatar, 4, 100, 100, 12, 16, 0);

        File tmp =  new File(imgPath);
        AnimatedGifEncoder e = new AnimatedGifEncoder();
        // 设置生成图片大小
        e.setSize(112, 112);
        //生成的图片路径
        e.start(new FileOutputStream(tmp));
        //图片之间间隔时间
        e.setDelay(delay);
        //重复次数 0表示无限重复 默认不重复
        e.setRepeat(0);
        //添加图片
        e.addFrame(p1);
        e.addFrame(p2);
        e.addFrame(p3);
        e.addFrame(p4);
        e.addFrame(p5);
        e.finish();
        return tmp;
    }

    //w: 宽 h: 高 x,y: 头像位置 hy:手的y轴偏移
    private BufferedImage processImage(Image image, Integer i, Integer w, Integer h, Integer x, Integer y, Integer hy) throws IOException {
        BufferedImage handImage = ImageIO.read(PatHeadPlugin.class.getResourceAsStream("/data/patHead/img"+i+".png"));
        BufferedImage processingImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        BufferedImage processedImage = new BufferedImage(112, 112, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = processingImage.createGraphics();
        graphics2D.drawImage(image, 0, 0, w, h, null);
        graphics2D.dispose();
        graphics2D = processedImage.createGraphics();
        graphics2D.setColor(Color.WHITE);
        graphics2D.fillRect(0, 0, 112, 112);
        graphics2D.drawImage(processingImage, x, y, null);
        graphics2D.drawImage(handImage, 0, hy, null);
        graphics2D.dispose();
        return processedImage;
    }
}
